package com.luo.chengrui.module.sa.service.matrix;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import com.luo.chengrui.module.sa.constant.SaConstants;
import com.luo.chengrui.module.sa.controller.admin.org.vo.OrgPageReqVO;
import com.luo.chengrui.module.sa.convert.org.OrgConvert;
import com.luo.chengrui.module.sa.dal.dataobject.matrix.OporgManagerMatrixDO;
import com.luo.chengrui.module.sa.dal.dataobject.org.OrgDO;
import com.luo.chengrui.module.sa.dal.mysql.matrix.OporgManagerMatrixMapper;
import com.luo.chengrui.module.sa.enums.GlobalStatusEnum;
import com.luo.chengrui.module.sa.service.org.OrgService;
import com.google.gson.Gson;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import com.luo.chengrui.module.sa.controller.admin.matrix.vo.*;
import com.luo.chengrui.module.sa.dal.dataobject.matrix.OporgManagerMatrixConfigDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import com.luo.chengrui.module.sa.convert.matrix.OporgManagerMatrixConfigConvert;
import com.luo.chengrui.module.sa.dal.mysql.matrix.OporgManagerMatrixConfigMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.luo.chengrui.module.sa.enums.ErrorCodeConstants.*;;

/**
 * 组织管理矩阵人员落位表  Service 实现类
 *
 * @author luodz
 */
@Service
@Validated
public class OporgManagerMatrixConfigServiceImpl implements OporgManagerMatrixConfigService {

    @Resource
    private OporgManagerMatrixConfigMapper oporgManagerMatrixConfigMapper;
    @Resource
    private OporgManagerMatrixMapper oporgManagerMatrixMapper;
    @Resource
    private OrgService orgService;

    @Override
    public String createOporgManagerMatrixConfig(OporgManagerMatrixConfigCreateReqVO createReqVO) {
        // 插入
        OporgManagerMatrixConfigDO oporgManagerMatrixConfig = OporgManagerMatrixConfigConvert.INSTANCE.convert(createReqVO);
        oporgManagerMatrixConfigMapper.insert(oporgManagerMatrixConfig);
        // 返回
        return oporgManagerMatrixConfig.getId();
    }

    @Override
    public void updateOporgManagerMatrixConfig(OporgManagerMatrixConfigUpdateReqVO updateReqVO) {
        // 校验存在
        validateOporgManagerMatrixConfigExists(updateReqVO.getId());
        // 更新
        OporgManagerMatrixConfigDO updateObj = OporgManagerMatrixConfigConvert.INSTANCE.convert(updateReqVO);
        oporgManagerMatrixConfigMapper.updateById(updateObj);
    }

    @Override
    public void deleteOporgManagerMatrixConfig(String id) {
        // 校验存在
        validateOporgManagerMatrixConfigExists(id);
        // 删除
        oporgManagerMatrixConfigMapper.deleteById(id);
    }

    private void validateOporgManagerMatrixConfigExists(String id) {
        if (oporgManagerMatrixConfigMapper.selectById(id) == null) {
            throw exception(OPORG_MANAGER_MATRIX_CONFIG_NOT_EXISTS);
        }
    }

    @Override
    public OporgManagerMatrixConfigDO getOporgManagerMatrixConfig(String id) {
        return oporgManagerMatrixConfigMapper.selectById(id);
    }

    @Override
    public List<OporgManagerMatrixConfigDO> getOporgManagerMatrixConfigList(Collection<String> ids) {
        return oporgManagerMatrixConfigMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<OporgManagerMatrixConfigDO> getOporgManagerMatrixConfigPage(OporgManagerMatrixConfigPageReqVO pageReqVO) {
        return oporgManagerMatrixConfigMapper.selectPage(pageReqVO);
    }

    @Override
    public List<OporgManagerMatrixConfigDO> getOporgManagerMatrixConfigList(OporgManagerMatrixConfigExportReqVO exportReqVO) {
        return oporgManagerMatrixConfigMapper.selectList(exportReqVO);
    }

    @Override
    public OporgManagerMatrixConfigDataRespVO getOporgManagerMatrixConfigDataList(String matrixId) {
        // 查询出机构树
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        List<OrgDO> orgList = orgService.getOrgAllList(new OrgPageReqVO(), SaConstants.DATA_PERMISSION_SUB_CODE_ORGMATRIXCONFIG);
        // 查询矩阵配置数据
        List<OporgManagerMatrixConfigDO> configList = oporgManagerMatrixConfigMapper.selectList(new OporgManagerMatrixConfigExportReqVO().setMatrixId(matrixId));
        // 装配前端数据结构
        OporgManagerMatrixConfigDataRespVO respVO = new OporgManagerMatrixConfigDataRespVO();
        respVO.setOrgList(OrgConvert.INSTANCE.convertList(orgList));
        respVO.setDataList(OporgManagerMatrixConfigConvert.INSTANCE.convertList(configList));
        return respVO;
    }

    @Override
    public OporgManagerMatrixConfigDataRespVO getOporgManagerMatrixDataList4Use() {
        // 查询出机构树
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        List<OrgDO> orgList = orgService.getOrgAllList(new OrgPageReqVO(), SaConstants.DATA_PERMISSION_SUB_CODE_ORGMATRIXCONFIG);
        // 查询有效的矩阵
        OporgManagerMatrixDO matrixDO = oporgManagerMatrixMapper.selectOne(new LambdaQueryWrapperX<OporgManagerMatrixDO>()
                .eqIfPresent(OporgManagerMatrixDO::getStatus, GlobalStatusEnum.ENABLED.getId()));
        // 查询矩阵配置数据
        List<OporgManagerMatrixConfigDO> configList = oporgManagerMatrixConfigMapper.selectList(new OporgManagerMatrixConfigExportReqVO().setMatrixId(matrixDO.getId()));
        // 装配前端数据结构
        OporgManagerMatrixConfigDataRespVO respVO = new OporgManagerMatrixConfigDataRespVO();
        respVO.setOrgList(OrgConvert.INSTANCE.convertList(orgList));

        //TODO 在使用矩阵时，不需要显示落位数据；
        respVO.setDataList(OporgManagerMatrixConfigConvert.INSTANCE.convertList(configList));
        return respVO;
    }

    @Override
    public OporgManagerMatrixPersonRespVO getOrgManagerMatrixPerson(OporgManagerMatrixConfigReqVO vo) {
        // 做矩阵配置验证时，传递了矩阵id；但在正式使用时不知道矩阵ID，所以需要查询租户当前生效的矩阵。（当前一个租户只允许有一个有效矩阵存在）
        if (StrUtil.isEmpty(vo.getMatrixId())) {
            // 查询有效矩阵
            OporgManagerMatrixDO matrixDO = oporgManagerMatrixMapper.selectOne(new LambdaQueryWrapperX<OporgManagerMatrixDO>()
                    .eqIfPresent(OporgManagerMatrixDO::getStatus, GlobalStatusEnum.ENABLED.getId()));
            if (matrixDO == null) {
                exception(NOT_VILID_OPORG_MANAGER_MATRIX);
            }
            vo.setMatrixId(matrixDO.getId());
        }
        OporgManagerMatrixPersonRespVO respVO = new OporgManagerMatrixPersonRespVO();
        OrgDO orgDO = orgService.getOrg(vo.getOrgId());
        if (Objects.isNull(orgDO)) {
            throw exception(ORG_NOT_EXISTS);
        }
        vo.setOrgFullId(orgDO.getFullId());

        List<OporgManagerMatrixConfigDO> matrixConfigDOList = oporgManagerMatrixConfigMapper.selectListV1(vo);

        if (matrixConfigDOList == null || matrixConfigDOList.isEmpty()) {
            return null;
        }

        Collections.sort(matrixConfigDOList, Comparator.comparingInt(o -> -o.getOrgFullId().length()));
        OporgManagerMatrixConfigDO orgConfig = matrixConfigDOList.get(0);
        respVO.setMatrixConfig(OporgManagerMatrixConfigConvert.INSTANCE.convert(orgConfig));
        String dataValues = orgConfig.getDataValues();

        JSONArray jsonArray = new JSONArray(dataValues);
        Gson gson = new Gson();
        List<OporgManagerMatrixConfigDataValue> dataValueList = jsonArray.stream().map(o -> gson.fromJson(o.toString(), OporgManagerMatrixConfigDataValue.class)).collect(Collectors.toList());

        List<String> personFullIds = dataValueList.stream().map(o -> o.getOrgFullId()).collect(Collectors.toList());
        List<OrgDO> personList = orgService.getPsmListByFullIds(personFullIds);
        respVO.setPersonList(personList);

        return respVO;
    }
}
